<!DOCTYPE html>
<html>
<head>
  <title>百亿补贴专场</title>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
  <link rel="stylesheet" href="https://cdn.staticfile.org/minireset.css/0.0.2/minireset.css">
  <link rel="stylesheet" href="https://at.alicdn.com/t/font_1534407_wi64k0vyd6o.css">
  <script src="https://cdn.staticfile.org/promise-polyfill/8.2.0/polyfill.min.js"></script>
  <script src="https://cdn.staticfile.org/jquery/2.2.4/jquery.min.js"></script>
  <script src="https://cdn.staticfile.org/vue/3.0.11/vue.global.js"></script>
  <script src="https://cdn.staticfile.org/vant/3.0.15/vant.min.js"></script>
  <link href="https://cdn.staticfile.org/vant/3.0.15/index.min.css" rel="stylesheet"><!--pc端click代替touch-->
  <script src="https://cdn.jsdelivr.net/npm/@vant/touch-emulator"></script>
  <meta name="referrer" content="no-referrer">
  <script src="https://cdn.jsdelivr.net/npm/@mxssfd/ts-utils@2.11.17/lib-umd/index.min.js"></script>
  <script src="https://img.bc.haodanku.com/cms/utils.v1_0_5.js"></script>
  <script
    defer>document.write("<link rel=\"stylesheet\" href=\"https://img.bc.haodanku.com/cms/tb_subsidies.css?t=" + (Date.now() - Date.now() % (60 * 1000)) + "\"/>");</script>
</head>
<body>
<template id="c-share">
  <div class="footer-share">
    <div class="btn share" v-on:click="handleShare">
    </div>
  </div>
</template>
<script>
var share = Vue.defineComponent({
  template: "#c-share",
  setup: function(props, ctx) {
    return {
      handleShare: function() {
        ctx.emit("share");
      }
    };
  }
});
</script>
<template id="c-list-item">
  <div class="goods-card">
    <div class="img-box cover">
      <img class="cover-img" v-lazy="item.itempic">
      <div class="icon">
        <img class="brand" v-bind:src="logo" alt="">
        <img class="bg" src="http://img-haodanku-com.cdn.fudaiapp.com/FuoKw0VnR3XNQoNmcGXIQOe8qssX" alt="">
        <div class="text">品牌正品</div>
      </div>
    </div>
    
    <div class="detail">
      <div class="title">
        <img
          class="icon"
          src="https://img.bc.haodanku.com/cms/logo_jhs.png"
          alt="">
        <span class="ellipsis-single">{{ item.itemshorttitle || item.itemtitle }}</span>
      </div>
      <div class="row row-2" v-bind:class="{'hidden':!item.activity_tag}">
        <img v-for="item in item.activity_tag" v-bind:src="item" alt="">
      </div>
      <div class="row row-3" v-bind:class="{'hidden':!item.coupon_info}">
        <img src="http://img-haodanku-com.cdn.fudaiapp.com/FtjSkLubVJ7qtA0cbVqu0dp_ipul" alt="">
        <span>{{item.coupon_info}}</span>
      </div>
      <div class="footer">
        <div class="price">
          <div class="discount">补贴券后价￥<strong>{{ Number(item.itemendprice) }}</strong></div>
          <div class="origin">￥{{ originPrice }}</div>
        </div>
      </div>
      <div class="btn-block">
        <div class="btn-order">
          <span class="operation" v-on:click.capture="buy($event)">立即购买</span>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
var listItem = Vue.defineComponent({
  template: "#c-list-item",
  props: {item: Object},
  setup: function(props, ctx) {
    var originPrice = Number(props.item.itemreserveprice);
    var coupon = Number(props.item.couponmoney);
    var logo = props.item.brand_pic;
    return {
      originPrice: originPrice,
      logo: logo || "",
      coupon: coupon,
      buy: function(e) {
        this.$parent.handleGoodsTransfer(e, this.item);
      }
    };
  }
});
</script>
<template id="scroll-nav">
  <div class="scroll-nav" v-bind:class="{'mainnav-fixed': mainnavFixed}" v-on:click.stop>
    <div class="mainnav" ref="mainnav">
      <div class="mainnav-content">
        <div class="partnav" ref="partnav">
          <div class="partnavlist" ref="partnavlist">
            <ul v-bind:class="{open: showMore}">
              <li
                v-bind:ref="setItemRef"
                v-for="(item, index) in list"
                v-on:click="onclickcategoryNav(item,index)"
                v-bind:class="{ 'active': activeValue === item[valueKey] }"
              >
                <i class="iconfont hdk-dizhi" v-if="activeValue === item[valueKey]"></i>
                <span>{{item[labelKey]}}</span>
              </li>
            </ul>
          </div>
        </div>
        <div class="morenav" v-on:click="openList()" ref="morenavElement"
             v-bind:style="showMore ? 'border-left: 1px solid #f5f5f5;' : 'box-shadow: 0px 0px 12px #ccc;'">
          <i class="iconfont hdk-paixu2" v-if="!showMore"></i>
          <i class="iconfont hdk-paixu" v-if="showMore"></i>
        </div>
      </div>
      <div class="opennav" v-if="showMore">
        <ul>
          <li
            class="btn"
            ref="navlistli"
            v-for="(item,index) in list"
            v-bind:class="{active:activeValue === item[valueKey]}"
            v-on:click="onclickcategoryNav(item,index)"
          >
            <div class="ellipsis-single">{{item[labelKey]}}</div>
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>
<script>
window.useScrollNav = function() {
  return Vue.defineComponent({
    template: "#scroll-nav",
    props: {
      list: {
        type: Array,
        required: true
      },
      value: {
        type: [String, Number],
        required: true
      },
      valueKey: {
        type: String,
        default: "value"
      },
      labelKey: {
        type: String,
        default: "label"
      },
      scrollFixed: {
        type: Boolean,
        default: true
      }
    },
    emits: ["update:value", "change"],
    setup: function(props, ctx) {
      var propsRefs = Vue.toRefs(props);
      var mainnav = Vue.ref();

      let itemRefs = [];
      const setItemRef = function(el) {
        if(el) {
          itemRefs.push(el);
        }
      };
      Vue.onBeforeUpdate(function() {
        itemRefs = [];
      });

      var data = {
        mainnavFixed: Vue.ref(false),
        showMore: Vue.ref(false),
        activeValue: Vue.ref("")
      };
      Vue.watch(propsRefs.value, function(n) {
        data.activeValue.value = n;
      });
      Vue.onMounted(function() {
        data.activeValue.value = propsRefs.value.value;
        window.addEventListener("click", function() {
          data.showMore.value = false;
        });
        if(props.scrollFixed) {
          setTimeout(function() {
            isFixed(mainnav.value, function(fixed) {
              data.mainnavFixed.value = fixed;
            });
          }, 500);
        }
      });
      var methods = {
        onclickcategoryNav: function(item, index) {
          item = Vue.toRaw(item);
          var valueKey = propsRefs.valueKey.value;
          var value = item[valueKey];
          if(value === data.activeValue.value) return;
          data.activeValue.value = value;
          this.$emit("update:value", value);
          this.$emit("change", {value: value, index: index});
          // 整条分类的宽度
          var mainnav_w = this.$refs.mainnav.offsetWidth;
          // 获取单个元素宽度
          var navli_w = itemRefs[index].offsetWidth;
          // 居中的元素距离左右两边的宽度
          var nav_distance = (mainnav_w - navli_w) / 2;
          // 被点击元素距离左边的距离
          var navli_left = parseInt(itemRefs[index].offsetLeft);
          var part_nav_width = this.$refs.partnav.offsetWidth;
          var part_nav_list_width = this.$refs.partnavlist.offsetWidth;
          var nav_offsetLeft = "";
          if(navli_left <= nav_distance) {
            nav_offsetLeft = 0;
          } else if(nav_distance - navli_left <= part_nav_width - part_nav_list_width) {
            nav_offsetLeft = part_nav_width - part_nav_list_width;
          } else {
            nav_offsetLeft = nav_distance - navli_left;
          }
          $(this.$refs.partnav).animate({
            "scrollLeft": -nav_offsetLeft
          }, 300);
          if(data.showMore.value) {
            data.showMore.value = false;
          }
        },
        /**
         * 展开所有分类
         */
        openList: function() {
          data.showMore.value = !data.showMore.value;
        }
      };
      return Object.assign({mainnav: mainnav, setItemRef: setItemRef}, data, methods);
    }
  });
};
</script>

<div id="single-page-app" v-cloak>
  <div class="page-container">
    <div class="banner-wrapper" ref="bannerRef"><img class="free-banner" v-bind:src="banner" alt=""></div>
    <div class="fixed-box" v-sticky="{type:'fixed',offsetTop:0}" key="fixed-block">
      <div class="search-box" v-bind:class="{focus:inputFocus,'has-value': search.value}">
        <van-search v-model="search.value" show-action placeholder="输入商品名称" clear-trigger="always"
                    v-on:focus="inputFocus = true" v-on:blur="inputFocus = false" v-on:search="onSearch"
                    v-on:clear="onClear" left-icon=" iconfont hdk-sousuo">
          <template v-slot:action>
            <div v-on:click="onSearch">搜索</div>
          </template>
        </van-search>
      </div>
      <div class="category">
        <scroll-nav v-if="category.list.length&gt;6" v-bind:list="category.list" v-model:value="category.value"
                    v-on:change="onNavChange" value-key="category_id" label-key="category_name"
                    v-bind:scroll-fixed="false"></scroll-nav>
      </div>
    </div>
    <div class="page-content" ref="list" v-bind:class="{'empty-list':!listData.list.length}">
      <div class="lists">
        <template v-if="listData.list.length || listData.finished">
          <list-item v-for="(item, index) in listData.list" v-bind:item="item" v-bind:key="item.item_id"
                     v-on:buy="handleGoodsTransfer($event,item,'link')"
                     v-on:share="handleGoodsTransfer($event,item,'copy')"></list-item><!-- 底部提示 -->
          <div class="list-item-loading"><span v-if="listData.finished">没有更多商品了~</span><span v-else>数据正在赶来的路上...</span>
          </div>
        </template><!-- 加载效果 -->
      </div>
    </div>
    <div class="btn back-top" v-show="scrollTop > 600" v-on:click="backTop"></div>
    <share v-on:share="handleShare"></share>
    <van-overlay v-bind:show="loading">
      <van-loading color="#0094ff"></van-loading>
    </van-overlay>
  </div>
</div>
<script>
const listDataStr = JSON.stringify({
  list: [],
  loading: false,
  finished: false,
  min_id: 1,
  pageTotal: 1,
  pageCurrent: 0
});


// 根据微信浏览器缩放比例设置rem缩放
if(inWechat() && "ontouchstart" in window) {
  const scale = getFontScale(true);
  document.documentElement.style.fontSize = "calc(100vw / 7.5 * " + scale + ")";
}

const scrollTop = Vue.ref(0);
const listData = Vue.reactive(JSON.parse(listDataStr));

function useBaseMixinCreated(getListData) {
  Vue.onBeforeMount(function() {
    getListData();
  });
}

function useScrollEndMounted(onScrollEnd, onNotScrollEnd) {
  Vue.onMounted(function() {
    window.addEventListener("scroll", function(ev) {
      scrollTop.value = document.documentElement.scrollTop || document.body.scrollTop;
      if(isScrollEnd(this, "vertical", 40)) {
        onScrollEnd();
      } else {
        onNotScrollEnd && onNotScrollEnd();
      }
    });
  });
}

function useBaseData() {
  return {
    scrollTop: scrollTop,
    listData: listData
  };
}

function useBaseMethods() {
  return {
    onScrollEnd: function() {
      this.getListData();
    },
    handleShare: function() {
      copy(location.href, "复制成功，分享给身边好友吧~");
    },
    resetListData: function() {
      Object.assign(listData, JSON.parse(listDataStr));
    }
  };
}

window.onload = function() {
  sticky.mounted = sticky.inserted;
  sticky.beforeUnmount = sticky.unbind;
  delete sticky.inserted;
  delete sticky.unbind;
  var app = Vue.createApp({
    directives: {
      sticky: sticky
    },
    components: {
      "list-item": listItem,
      share: share,
      "scroll-nav": useScrollNav()
    },
    setup: function(props, ctx) {
      var bannerRef = Vue.ref();
      var commonData = useCommon();
      var data = Object.assign(
        {},
        {
          banner: "https://img.bc.haodanku.com/cms/tb_subsidies_banner.png",
          top: 0,
          loading: Vue.ref(false),
          search: Vue.reactive({
            value: "",
            hotkey: []
          }),
          inputFocus: Vue.ref(false),
          category: Vue.reactive({
            value: 0,
            list: []
          })
        },
        useBaseData(),
        commonData
      );
      var methods = {
        onSearch() {
          data.category.value = data.category.list[0].category_id;
          methods.reGetListData();
        },
        onNavChange() {
          methods.reGetListData();
        },
        onClear() {
          data.search.value = "";
          methods.reGetListData();
        },
        backTop: function() {
          $("html,body").animate({scrollTop: 0});
        },
        resetListData: function() {
          Object.assign(data.listData, JSON.parse(listDataStr), {list: data.listData.list});
        },
        reGetListData: function() {
          methods.resetListData();
          $("html,body").animate({scrollTop: $(".banner-wrapper").height()});
          return methods.getListData(true);
        },

        /**
         * @param {boolean?} [clean = false]
         * @return {Promise<any>}
         */
        getListData: function(clean = false) {
          var loading = data.loading;
          var listData = data.listData;
          if(loading.value || listData.loading || listData.finished) return Promise.reject();
          listData.loading = true;
          if(clean) {
            loading.value = true;
          }
          var min_size = 10;
          var params = Object.assign(
            {
              min_id: data.listData.min_id,
              min_size: min_size,
              category_id: data.category.value,
              keyword: data.search.value
            },
            data.getListDataParams()
          );
          var obj = Request.get(url("v2.api.haodanku.com/cash_subsidy_goods"), params);
          obj.promise.then(function(res) {
            var list = res.data || [];
            if(!data.category.list.length) {
              data.category.list = res.category || [];
              // data.category.value = data.category.list[0].category_id;
            }
            setTimeout(function() {
              if(clean) {
                listData.list = list;
              } else {
                listData.list = listData.list.concat(list);
              }
              listData.finished = listData.min_id == res.min_id || !list.length || list.length < min_size;
              listData.min_id = res.min_id || listData.min_id;
            }, 200);
          }).catch(function() {
            if(clean) {
              listData.list = [];
            }
            listData.finished = true;
          }).finally(tsUtils.debounce(function() {
            listData.loading = false;
            loading.value = false;
          }, 200));
          return obj.promise;
        },
        /**
         * 商品转链
         * @param e {MouseEvent}
         * @param item
         */
        handleGoodsTransfer: function(e, item) {
          var key = "transfer";

          function errorCB(res) {
            toast(res.msg || "转链失败");
          }

          var param = Object.assign({
            itemid: item.item_id,
            title: item.itemshorttitle,
            is_special: 2
          }, finalData.getTransferParams());

          var exec = function() {
            copy(item[key], "复制口令成功,请打开淘宝领取", "复制口令失败,请点击重试", true);
          };
          // 已经转过链 直接复制
          if(item[key]) {
            exec();
            return;
          }
          var el = e.currentTarget.parentNode;
          tsUtils.onceEvent(el, "click", exec);
          // 处理转链
          useResolveTransferResult(url("v2.api.haodanku.com/ratesurl"), item, key, param).catch(errorCB);
        }
      };

      methods = Object.assign(useBaseMethods(), methods);

      useScrollEndMounted(methods.getListData);
      Vue.onMounted(() => methods.getListData(true));
      var computed = {};
      var finalData = Object.assign({bannerRef: bannerRef}, data, methods, computed);
      return finalData;
    }
  });

  app.use(vant);
  app.use(vant.Lazyload, {
    lazyComponent: true,
    preLoad: 1.3,
    error: "http://img.bc.haodanku.com/haodanku/1595237918",
    loading: "http://img.bc.fqapps.com/fudai13cae4ae6ef16739ed3b100a2ec39e97.gif",
    attempt: 1
  });
  app.mount("#single-page-app");
};
</script>
<script>
function useCommon() {
  var commonParams = {
    apikey: "" //必填
  };
  return {
    commonParams: commonParams,
    // 列表参数
    getListDataParams: function() {
      return commonParams;
    },
    // 转链参数
    getTransferParams: function(item) {
      return Object.assign({
        pid: "",//必填
        tb_name: ""//必填
      }, this.commonParams);
    }
  };
}

// 处理转链
function useResolveTransferResult(url, item, key, param) {
  return Request.postSync(url, param, function(res) {
    item[key] = "0" + res.data.special.special_code + "/";
  }).promise;
}
</script>
</body>
</html>